home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_100
/
146_01
/
ccint.txt
< prev
next >
Wrap
Text File
|
1985-03-09
|
24KB
|
1,328 lines
ORG 0
NAM SMALL-C INTERPRETER
OPT NOP,NOG
*
* LAST UPDATE 9-SEP-82
*
JMP BEGIN START THE INTERPRETER
* AN INDIRECT CALL TABLE
NOP PUT ON A BOUNDARY OF 4
FCB 86
JMP fclose+1
FCB 86
JMP fopen+1
FCB 86
JMP getc+1
FCB 86
JMP getchar+1
FCB 86
JMP gets+1
FCB 86
JMP putc+1
FCB 86
JMP putchar+1
FCB 86
JMP puts+1
NOP
JMP RTSC
FCB 86
JMP isalpha+1
FCB 86
JMP isdigit+1
FCB 86
JMP isalnum+1
FCB 86
JMP islower+1
FCB 86
JMP isupper+1
FCB 86
JMP isspace+1
FCB 86
JMP toupper+1
FCB 86
JMP tolower+1
FCB 86
JMP strclr+1
FCB 86
JMP strlen+1
FCB 86
JMP strcpy+1
FCB 86
JMP strcat+1
FCB 86
JMP strcmp+1
RMB 4*4 ROOM FOR 4 MORE
LIB FLEXPTRS
NFILES EQU 4 MAX NO OF DISK FILES OPEN AT ONCE
PC RMB 2 PSEUDO PROGRAM COUNTER
R1A RMB 1 WORKING 16 BIT
R1B RMB 1 --REGISTER
DFLAG FCB NFILES-1 DIVIDE ROUTINE FLAG
STEMP RMB 2 TEMP STORAGE FOR STACK POINTER
X1TMP RMB 2 TEMP STORAGE FOR X REG
X2TMP RMB 2 ... DITTO ...
FCBPTR RMB 2 POINTER INTO FCB TABLE
FCBTBL FDB FCB TABLE OF FCB POINTERS
RMB NFILES*2 ROOM FOR THE REST
***************************************************
BEGIN LDX #FCBTBL+2 POINT TO FCB ADDRESSES
LDA A #NFILES-1
STA A DFLAG INIT COUNTER
LDA A $AC2B GET TOP OF MEMORY
LDA B $AC2C
BLOOP SUB B #$40 SUBTR 320 (SIZE OF FCB)
SBC A #1
STA A 0,X SAVE FCB ADDRESS
INX
STA B 0,X
INX
DEC DFLAG DONE ???
BNE BLOOP
CLR 0,X MARK END OF TABLE
CLR 1,X
STA A STEMP TOP OF STACK AREA
STA B STEMP+1
LDX STEMP
TXS SET STACK POINTER
LDX #FCBTBL POINT TO TABLE OF FCB ADDRESSES
Init STX FCBPTR
LDX 0,X GET FCB ADDRESS
BEQ Initend QUIT IF END OF TABLE
CLR 2,X MARK AS NOT IN USE
LDX FCBPTR
INX
INX
BRA Init
Initend LDX #$800
BRA NEXT2 START THE INTERPRETATION
**************************************************************
*
* THE HEART OF THE INTERPRETER--- NEXT INSTRUCTION FETCHER.
*
BUMP2 LDX PC GET PROG COUNTER
BUMP2A INX INCR BY 2
INX
BRA NEXT1 FETCH NEXT INSTRUCTION
NEXT LDX PC
NEXT1 STA A R1A SAVE THE WORK
STA B R1B --REGISTER
NEXT2 LDA B 0,X GET THE PSEUDO-INSTRUCTION
INX (B CONTAINS A TABLE OFFSET)
STX PC SAVE NEW PC
STA B JJJ+2 SAVE AS PAGE OFFSET
LDA B R1B RESTORE
JJJ LDX JTABLE POINT TO ROUTINE (SELF MODIFYING CODE)
JMP 0,X GO EXECUTE THE PSEUDO-INSTR.
**************************************************************
* THE JUMP TABLE *
**************************************************************
ORG *+255/256*256 MUST START ON A PAGE BOUNDARY
JTABLE FDB LD1IM #0
FDB LD1SOFF #1
FDB LD1 #2
FDB LDB1 #3
FDB LD1R #4
FDB LDB1R #5
FDB ST1 #6
FDB STB1 #7
FDB ST1SP #8
FDB STB1SP #9
FDB PUSHR1 #10
FDB EXG1 #11
FDB JMPL #12
FDB BRZL #13
FDB JSRL #14
FDB JSRSP #15
FDB RTSC #16
FDB MODSP #17
FDB DBL1 #18
FDB ADDS #19
FDB SUBFST #20
FDB MUL1 #21
FDB DIV1 #22
FDB MOD #23
FDB ORS #24
FDB XORS #25
FDB ANDS #26
FDB ASRS #27
FDB ASLS #28
FDB NEGR #29
FDB NOTR #30
FDB INCR #31
FDB DECR #32
FDB ZEQ #33
FDB ZNE #34
FDB ZLT #35
FDB ZLE #36
FDB ZGT #37
FDB ZGE #38
FDB ULT #39
FDB ULE #40
FDB UGT #41
FDB UGE #42
FDB ASMC #43
*************************************************************
*-------------------------
* #0 LOAD REG WITH IMMED. VALUE
LD1IM LDX PC
LDA A 0,X HIGH BYTE
LDA B 1,X LOW BYTE
JMP BUMP2A
*-------------------------
* #1 LOAD STACK ADDRESS + OFFSET INTO REG
LD1SOFF STS R1A SAVE STACK VALUE
LDX PC
LDA A 0,X GET OFFSET
LDA B 1,X -- VALUE
SEC
ADC B R1B ADD OFFSET + 1
ADC A R1A
JMP BUMP2A
*-------------------------
* #2 LOAD WORD @ ADDRESS
LD1 LDX PC
LDX 0,X GET ADDRESS
LD1A LDA A 0,X GET WORD
LDA B 1,X
JMP BUMP2
*-------------------------
* #3 LOAD BYTE @ ADDRESS
LDB1 LDX PC
LDX 0,X GET ADDRESS
CLR A
LDA B 0,X GET BYTE
BPL LDB1A
COM A SIGN EXTEND
LDB1A JMP BUMP2
*-------------------------
* #4 LOAD WORD INDIRECT (ADDR IN REG)
LD1R LDX R1A GET ADDRESS
LDA A 0,X GET WORD
LDA B 1,X
JMP NEXT
*-------------------------
* #5 LOAD BYTE INDIRECT (ADDR IN REG)
LDB1R LDX R1A
CLR A
LDA B 0,X GET BYTE
BPL LDB1RA
COM A
LDB1RA JMP NEXT
*-------------------------
* #6 STORE WORD @ ADDRESS
ST1 LDX PC
LDX 0,X GET ADDRESS
STA A 0,X STORE WORD
STA B 1,X
JMP BUMP2
*-------------------------
* #7 STORE BYTE @ ADDRESS
STB1 LDX PC
LDX 0,X GET ADDR
STA B 0,X STORE BYTE
JMP BUMP2
*-------------------------
* #8 STORE WORD @ ADDRESS ON STACK
ST1SP TSX STACK TO INDEX
LDX 0,X GET ADDRESS
STA A 0,X STORE WORD
STA B 1,X
INS
INS POP STACK
JMP NEXT
*-------------------------
* #9 STORE BYTE @ ADDRESS ON STACK
STB1SP TSX
LDX 0,X
STA B 0,X STORE BYTE
INS POP ...
INS
JMP NEXT
*-------------------------
* #10 PUSH WORD ON STACK
PUSHR1 PSH B
PSH A
LDX PC
JMP NEXT2
*-------------------------
* #11 SWAP REG AND TOP OF STACK
EXG1 TSX
LDX 0,X GET VALUE ON STACK
STX R1A SAVE
INS
INS
PSH B
PSH A REG ON STACK
LDA A R1A NEW REG
LDA B R1B
LDX PC
JMP NEXT2
*-------------------------
* #12 JUMP TO LABEL
JMPL LDX PC
JMP1 LDX 0,X GET ADDRESS (NEW PC)
JMP NEXT2
*-------------------------
* #13 JUMP TO LABEL IF FALSE
BRZL ORA A R1B SET FLAGS
BEQ JMPL IF REG=0 -- JUMP
JMP BUMP2 ELSE, PROCEED
*-------------------------
* #14 CALL TO LABEL
JSRL LDX PC
INX ADJUST RETURN
INX -- ADDRESS
DES
STS *+5 *** SELF MODIFYING CODE ***
DES
STX $FFFF PUSH RETURN ADDRESS
BRA JMPL
*-------------------------
* #15 CALL TO TOP OF STACK
JSRSP TSX POINT TO STACK
LDX 0,X GET ADDRESS (NEW PC)
INS POP
INS
LDA B PC+1 GET RETURN ADDRESS
PSH B
LDA B PC
PSH B SAVE RETURN ADDRESS
JMP NEXT2
*-------------------------
* #16 RETURN TO CALLER
RTSC TSX
LDX 0,X GET ADDRESS
INS POP
INS
JMP NEXT1
*-------------------------
* #17 MODIFY THE STACK POINTER
MODSP LDX PC
LDA A 0,X GET VALUE
LDA B 1,X
STS STEMP
ADD B STEMP+1 ADD STACK POINTER
ADC A STEMP
STA A STEMP
STA B STEMP+1
LDS STEMP NEW STACK POINTER
LDA A R1A RESTORE REGISTER
LDA B R1B
JMP BUMP2A
*---------------------------
* #18 DOUBLE THE PRIMARY REGISTER
DBL1 ASL B
ROL A
JMP NEXT
*---------------------------
* #19 ADD REG AND TOP OF STACK (THEN POP)
ADDS TSX
ADD B 1,X DO THE ADD
ADC A 0,X
JMP POPS POP & RETURN
*---------------------------
* #20 SUBTRACT REG FROM TOP OF STACK
SUBFST PUL A GET VALUE OFF STACK
PUL B
SUB B R1B SUBTRACT REGISTER
SBC A R1A
JMP NEXT
*---------------------------
* #21 MULTIPLY TOP OF STACK BY REG (RESULT IN REG)
MUL1 PSH B
PSH A REG ON STACK
LDA A #16
PSH A SET COUNTER
CLR A
CLR B
TSX POINT TO DATA
M2 ROR 3,X SHIFT MULTIPLIER
ROR 4,X
DEC 0,X DONE ?
BMI M4
BCC M3
ADD B 2,X
ADC A 1,X
M3 ROR A
ROR B SHIFT RESULT
BRA M2 AND LOOP
M4 INS CLEAN STACK
INS
INS
PUL A GET RESULT
PUL B
JMP NEXT
*-----------------------------
* #22 DIVIDE THE TOP OF STACK BY REG --- RESULT IN REG.
DIV1 BSR BDIV DO THE BASIC DIVIDE
LDA A DFLAG GET SIGN FLAG
AND A #1 MASK OFF BIT ZERO
PUL A GET RESULT
PUL B
BEQ DIV1R
DIV1N BSR NEGATE NEGATE THE VALUE IN A,B
DIV1R JMP NEXT
*-----------------------------
* #23 DIVIDE TOP OF STACK BY REG --- REMAINDER IN REG
MOD BSR BDIV
INS CLEAN STACK
INS
PSH A TEMP SAVE
LDA A DFLAG GET SIGN FLAG
BPL MOD1
COM A
MOD1 AND A #1 MASK OFF BIT 0
PUL A
BNE DIV1N IF BIT 0 SET, NEGATE
JMP NEXT
*****************************************************
* BASIC 16 BIT DIVIDE ROUTINE
* ENTER WITH: DIVIDEND ON STACK
* DIVISOR IN A,B
* EXIT WITH: QUOTIENT ON STACK
* REMAINDER IN A,B
* SIGN FLAG IN DFLAG
*
BDIV CLR DFLAG
TST A CHECK DIVISOR SIGN
BPL BDIV1
INC DFLAG ADJUST SIGN FLAG
BSR NEGATE TAKE ABSOLUTE VALUE
BDIV1 PSH B FORCE ON STACK
PSH A
LDA A #17 BIT COUNTER
PSH A
TSX POINT TO DATA
LDA A 5,X CHECK SIGN
BPL BDIV2 -- OF DIVIDEND
COM DFLAG A